/**
 *
 * 一个用于测量三维场景内的几何体的测量类 Measure.js
 *
 * Daniel
 *
 * 2018.03.12
 *
 * **/
define(function(){
    
    var Measure = function (world,handle) {
        
        
        this.distance='';
        
        this.mesureFlag=true;
        
        this.measureArray=[];
        this.measureIdArray=[];
        this.measureIdPointArray=[];
        this.lineObjectAr=[];
        
        this.measureObject={};
        this.measurePoint= {
            startPoint: [],
            endPoint: [],
        };
        
        this.pick = handle || new function () {};
        this.scene = world.scene || {};
        this.dom = world.dom.renDom;
        scope = this;
        
        
    };
    
    Object.assign(Measure.prototype,{
        
        //初始化
        start : function(boolean){
            if(boolean!==undefined){
                if(boolean){
                    scope.enable();
                }else{
                    scope.dispose();
                }
            }else{
                scope.dispose();
            }
            
        
    },
    
    
    //预览绘制
    measureLines : function(event,callback){
            if(scope.mesureFlag){
                if (event) event.preventDefault();
                var flagss = scope.pick.events.mouseMonitor(event);
                if (flagss.enable == false) return;
                if (flagss.flag == 0 && flagss.enable) {
                    scope.mesureFlag = true;
                    scope.measureStartPoint(event,callback);
                }
                if(flagss.flag == 2){
                    scope.mesureFlag = false;
                    scope.pick.events.removeEvent(scope.dom,"mousedown",scope.mousedown,false);
                    scope.pick.events.removeEvent(scope.dom,"mouseup",scope.mouseup,false);
                    scope.pick.events.removeEvent(scope.dom,"mousemove",scope.mousemove,false);
                }
                return scope;
            }
            
    },
    
    //执行测量
    mesure : function (event) {
            if(scope.mesureFlag){
                var toPoint,startPoint,endPoint,flag,pointCarrier;
                toPoint = scope.pick.select()(event);
                
                if( toPoint == undefined )return;
                
                flag = scope.measurePoint.startPoint;
                
                if(flag.length>0){
                    var start = scope.measureIdPointArray[0].clone();
                    var lines,flagss,name;
                    pointCarrier = scope.measureCompute(toPoint);
                    if(pointCarrier == undefined) return;
                    var obj = scope.createPoint(pointCarrier);
                    // var targetPoint = pointCarrier.target.parent.parent.position.clone();
                    endPoint = obj.originalV.clone();
                    name = "lines";
                    flagss = scope.lineObjectAr;
                    if( flagss.length > 0 ){
                        var deleteLine = scope.lineObjectAr[0];
                        scope.scene.remove(deleteLine);
                        scope.lineObjectAr = [];
                        scope.measurePoint.endPoint = [];
                        lines = scope.drawLine(start,endPoint,name);
                        scope.scene.add(lines);
                    }else{
                        lines = scope.drawLine(start,endPoint,name);
                        scope.scene.add(lines);
                    }
                    
                }
                else{
                    startPoint = scope.measureCompute(toPoint);
                    if(startPoint==undefined)return;
                    scope.createPoint(startPoint);
                }
            }
            return scope;
    },
    
    //移除测量
    removeMesure : function (){
            var points,line,fixLine,scene;
            points = scope.measureArray[0];
            line = scope.lineObjectAr[0];
            fixLine = scope.measureLine;
            scene = scope.scene;
            
            //移除现有的测量模型
            scene.remove(points);
            scene.remove(line);
            scene.remove(fixLine);
            
            //数据重置
            scope.measureArray.length =0;
            scope.measureIdArray.length =0;
            scope.lineObjectAr.length =0;
            scope.measureIdPointArray.length =0;
            scope.measurePoint.startPoint.length =0;
            scope.measureLine=null;
    },
    
    //确定起始点
    measureStartPoint : function (event,callback){
        if(event) event.preventDefault();
        if(scope.mesureFlag){
            var pickArray = scope.measureArray;
            if(pickArray.length>0){
                var scene = scope.scene;
                var pointObject = pickArray[0];
                var targetPoint = pointObject.originalV.clone();
                // var targetPoint = pointObject.target.parent.parent.position.clone();
                var start = targetPoint;
                var flag = scope.measureIdPointArray;
                if(pickArray){
                    var c = pickArray;
                    
                }
                pointObject.material.opacity = 1;
                pointObject.material.transparent = false;
                scope.measurePoint.startPoint.push(pointObject);
                scene.add(pointObject);
                if(flag.length==0){
                    this.measureIdPointArray.push(start);
                }
                if(flag.length>0){
                    var newStart = flag[0].clone();
                    var lines = scope.drawLine(newStart,start,"lineFox");
                    var lineObj = scope.measureLine;
                    // var matrix = pointObject.target.parent.matrixWorld;
                    //     matrix.decompose(lines.position,lines.quaternion,lines.scale);
                    if(lineObj == null){
                        scene.add(lines);
                    }
                    else{
                        scene.remove(lineObj);
                        scene.add(lines);
                    }
                    this.measureLine = lines;
                    
                    //模型的实际距离换算
                    var lengthss = newStart.distanceTo(start);
                    if( lengthss > 0 ){
                        this.distance = lengthss * 0.01;
                        //console.log("当前的长度为"+this.distance + "m");
                        if(callback)callback(scope.distance);
                    }
                }
            }
        }
    },
    
    //测量
    
    //测量讫始点计算
    measureCompute : function (targetObject) {
        if(targetObject.length>0){
            var mother = targetObject[0];
            var faceIndex = mother.face;
            var geometrys = mother.object.geometry;
            var matrix = mother.object.matrixWorld;
            var vectorV = geometrys.vertices;
            var pointTarget = mother.point;
            var id = mother.object.id;
            var parent = mother.object;
            
            var vertexAA = new THREE.Vector3(),
                vertexBB = new THREE.Vector3(),
                vertexCC = new THREE.Vector3();
            
            //算法辅助参数
            var vertexA,vertexB,vertexC,faceVertexA,faceVertexB,
                faceVertexC,lengthA,lengthB,lengthC,euler,
                idName,vectors,originalV,transitionA,transitionB,transitionC,
                matrixP,matrixS,matrixR,
                goal = {
                    matrix:     "",
                    id:         "",
                    vectors:    "",
                    originalV:  ""
                };
            
            faceVertexA = faceIndex.a;
            faceVertexB = faceIndex.b;
            faceVertexC = faceIndex.c;
            
            matrixP = new THREE.Vector3();
            matrixS = new THREE.Vector3();
            matrixR = new THREE.Quaternion();
            
            euler = new THREE.Euler();
            euler.set(-0.5*Math.PI,0,0);
            matrix.decompose(matrixP,matrixR,matrixS);
            transitionA = vectorV[faceVertexA].clone().multiplyScalar(matrixS.x);
            transitionB = vectorV[faceVertexB].clone().multiplyScalar(matrixS.x);
            transitionC = vectorV[faceVertexC].clone().multiplyScalar(matrixS.x);
            
            vertexAA.set(transitionA.x,transitionA.z + matrixP.y,-transitionA.y);
            vertexBB.set(transitionB.x,transitionB.z + matrixP.y,-transitionB.y);
            vertexCC.set(transitionC.x,transitionC.z + matrixP.y,-transitionC.y);
            
            vertexA = vectorV[faceVertexA];
            vertexB = vectorV[faceVertexB];
            vertexC = vectorV[faceVertexC];
            
            lengthA = vertexAA .distanceTo(pointTarget);
            lengthB = vertexBB .distanceTo(pointTarget);
            lengthC = vertexCC .distanceTo(pointTarget);
            
            //计算最近顶点
            if(lengthA<lengthB){
                if(lengthA<lengthC){
                    vectors = vertexA;
                    originalV = vertexAA;
                    idName = id + faceVertexA;
                }else{
                    vectors = vertexC;
                    originalV = vertexCC;
                    idName = id + faceVertexC;
                }
            }
            else{
                if(lengthB<lengthC){
                    vectors = vertexB;
                    originalV = vertexBB;
                    idName = id + faceVertexB;
                }else{
                    vectors= vertexC;
                    originalV = vertexCC;
                    idName = id + faceVertexC;
                }
            }
            
            //返回最佳值
            goal.matrix = matrix;
            goal.id = idName;
            goal.vectors = vectors;
            goal.originalV = originalV;
            goal.target = parent;
            return goal;
        }
    },
    
    //测量点绘制
    createPoint : function (vectorObject,names) {
        //显示单个定点
        var flag = this.measureIdArray.indexOf(id);
        if( flag ==-1 ){
            var id,name,matrix,sphereInter;
            sphereInter = this.PointGeom(vectorObject,names);
            id = sphereInter.id;
            var oldPoint = this.measureArray[0];
            this.scene.remove(oldPoint);
            this.measureArray.length =0;
            this.measureIdArray.length =0;
            this.measureArray.push(sphereInter);
            this.measureIdArray.push(id);
            matrix = vectorObject.matrix;
            matrix.decompose(sphereInter.position,sphereInter.quaternion,sphereInter.scale);
            
            this.scene.add(sphereInter);
            name = sphereInter.name;
            sphereInter.originalV = vectorObject.originalV;
            this.measureObject[""+ name +""] = sphereInter.clone();
        }
        return sphereInter;
    },
    
    //测量点模型
    PointGeom : function (vectorObject,names){
        var goldGeom = new THREE.Geometry();
        
        var goldmaterial = new THREE.PointsMaterial( { size: 15,color:0xff0000,depthTest : false,transparent : true});
        var vector = vectorObject.vectors;
        var id = vectorObject.id;
        
        goldmaterial.opacity = 0.75;
        goldmaterial.transparent = true;
        goldGeom.vertices.push(vector);
        var sphereInter = new THREE.Points( goldGeom, goldmaterial );
        var name = names || "point"+id;
        sphereInter.name = name;
        sphereInter.target = vectorObject.target;
        return sphereInter;
    },
    
    //测量线绘制
    drawLine : function (startPoint,targetPoint,names) {
        var id,name;
        var material = new THREE.LineBasicMaterial({
            depthTest : false,
            transparent : true,
            color: 0xe6135c
        });
        var geometry = new THREE.Geometry();
        geometry.vertices.push(startPoint, targetPoint);
        var line = new THREE.Line( geometry, material );
        id = line.id;
        name = names || "line" + id;
        line.name = name;
        this.measureArray.push(line);
        this.measureIdArray.push(id);
        this.lineObjectAr.push(line);
        return line;
    },
    
    //激活测量
    enable:function () {
        scope.pick.events.addEvent(scope.dom,"mousedown",scope.mousedown,false);
        scope.pick.events.addEvent(scope.dom,"mouseup",scope.mouseup,false);
        scope.pick.events.addEvent(scope.dom,"mousemove",scope.mousemove,false);
    },
    
    //关闭测量
    dispose:function () {
        scope.pick.events.removeEvent(scope.dom,"mousedown",scope.mousedown,false);
        scope.pick.events.removeEvent(scope.dom,"mouseup",scope.mouseup,false);
        scope.pick.events.removeEvent(scope.dom,"mousemove",scope.mousemove,false);
        scope.removeMesure();
    },
    
    //鼠标向下
    mousedown:function (event) {
        scope.measureLines(event);
        },
        
    //鼠标向上
    mouseup:function(event){
        scope.measureLines(event);
    },
        
    //鼠标移动
    mousemove:function (event) {
       scope.mesure(event);
    },
    
    });
    
    
    var scope;
    
    return Measure;
    
    
    
});